package com.base.servlet.core;

import com.base.servlet.http.HttpServlet;
import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>加载xml 配置文件</p>
 * <p>将映射关系加载到内存</p>
 *
 * @author: Jeffrey
 * @date: 2022/01/23/10:09
 * @description:
 */
@Slf4j
public class HandlerMapping {

    private static final String XML_PATH_DEFAULT = "assignment_meet/src/main/webapp/WEB-INF/web.xml";

    /**
     * (映射地址,(name,class))
     */
    private final Map<String, NameToClassMapping> mapping = new ConcurrentHashMap<>();

    public HandlerMapping(String location) {
        loadResources(location);
    }

    public HandlerMapping() {
        loadResources();
    }

    /**
     * 获取映射对应的Handler的Class文件
     * @param mappingPath 映射路径
     * @return Handler.class
     */
    public Class<HttpServlet> getHandlerClass(String mappingPath){
        return mapping.get(mappingPath).getAClass();
    }

    /**
     * 获取映射对应的Handler的名字
     * @param mappingPath 映射路径
     * @return Handler.servlet-name
     */
    public String getHandlerName(String mappingPath){
        return mapping.get(mappingPath).getName();
    }

    private void loadResources(String xmlLocation) {
        //创建一个DocumentBuilderFactory的对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        //创建DocumentBuilder对象
        DocumentBuilder db = null;
        try {
            db = dbf.newDocumentBuilder();
            Document document = db.parse(xmlLocation);
            //获取某一根节点下的所有标签

            NodeList servletList = document.getElementsByTagName("servlet");
            Map<String,Class> nameMapClass = new HashMap<>();
            for (int i = 0 ; i < servletList.getLength() ; i ++){
                Element node = (Element) servletList.item(i);
                String nameValue = node.getElementsByTagName("servlet-name")
                        .item(0)
                        .getFirstChild()
                        .getNodeValue();
                String classValue = node.getElementsByTagName("servlet-class")
                        .item(0)
                        .getFirstChild()
                        .getNodeValue();
                Class clazz = Class.forName(classValue);
                nameMapClass.put(nameValue,clazz);
            }

            NodeList servletMappingList = document.getElementsByTagName("servlet-mapping");
            for (int i = 0 ; i < servletMappingList.getLength() ; i++){
                Element node = (Element) servletMappingList.item(i);
                String nameValue = node.getElementsByTagName("servlet-name")
                        .item(0)
                        .getFirstChild()
                        .getNodeValue();

                String urlValue = node.getElementsByTagName("url-pattern")
                        .item(0)
                        .getFirstChild()
                        .getNodeValue();
                mapping.put(urlValue,new NameToClassMapping(nameValue,nameMapClass.get(nameValue)));
            }
        } catch (ParserConfigurationException | IOException | SAXException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    private void loadResources () {
        loadResources(XML_PATH_DEFAULT);
    }




}
